package com.stateflow.engine.aop;

import com.stateflow.facade.common.model.ToString;
import com.stateflow.facade.common.util.CommonUtils;
import com.stateflow.facade.common.util.JsonUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by weiqingming on 2020/1/28.
 */
@Aspect
@Component
public class ControllerLogAop {


    private static final Logger LOGGER = LoggerFactory.getLogger(ControllerLogAop.class);

    /** 定义切入点 */
    @Pointcut("execution(* com.stateflow.engine.user.web.*.*.*(..))")
    private void aspect() {
    }


    /** 定义前置通知 */
    @Before("aspect()")
    public void toBefore(JoinPoint joinPoint) {
        printLog(joinPoint);
    }


    /**
     * 打印日志
     * @param joinPoint
     */
    private void printLog(JoinPoint joinPoint){
        if (joinPoint instanceof MethodInvocationProceedingJoinPoint) {
            MethodInvocationProceedingJoinPoint mjp = (MethodInvocationProceedingJoinPoint) joinPoint;
            String paramJson = "";
            String className = mjp.getSignature().getDeclaringTypeName();
            String methodName = mjp.getSignature().getName();

            // 过滤不可序列化的
            List<Object> params = new ArrayList<>();
            for (Object item : mjp.getArgs()) {
                if (item instanceof ServletRequest || item instanceof ServletResponse || item instanceof MultipartFile) {
                    continue;
                }
                params.add(item);
            }

            // 入参转化成String Json
            if (params.size() == 1) {
                setTraceId(params.get(0));
                paramJson = JsonUtils.toJson(params.get(0));
            } else if (params.size() > 1){
                setTraceId(params.get(0));
                paramJson = JsonUtils.toJson(params);
            }

            StringBuilder log = new StringBuilder();
            log.append("收到HTTP请求：");
            log.append(className).append(".");
            log.append(methodName);
            log.append(" 入参：").append(paramJson);
            LOGGER.info(log.toString());
        }
    }


    /**
     * 设置traceId
     * @param param
     */
    private void setTraceId(Object param){
        if (param instanceof ToString){
            ToString p = (ToString) param;
            p.setTraceId(CommonUtils.getUUID().replace("-", ""));
        }
    }
}
